package jp.sourceforge.talisman.mds.distance;

/*
 * $Id: NormalizedEuclideanItemDistanceCalculator.java,v 1.1 2009/09/12 05:06:09 weiwei Exp $
 */

/**
 * Normalized euclidean distance calculator.
 * <pre>
 * D(x, y) = \sqrt{\sigma^r_{k=1} (z_{xk} - z_{yk})^2}
 * z_{x} = \frac{x - \bar{x}}{\frac{2}{x}}
 * </pre>
 *
 * @author Haruaki Tamada
 * @version $Revision: 1.1 $ 
 */
public class NormalizedEuclideanItemDistanceCalculator extends AbstractItemDistanceCalculator{
    @Override
    public double calculate(double[] x, double[] y){
        validateArguments(x, y);

        double xbar = calculateBar(x);
        double ybar = calculateBar(y);
        double value = 0d;
        for(int i = 0; i < x.length; i++){
            if(!Double.isNaN(x[i]) && !Double.isNaN(y[i])){
                double zx = (x[i] - xbar) / (2 / x[i]);
                double zy = (y[i] - ybar) / (2 / y[i]);
                value += (zx - zy) * (zx - zy);
            }
        }

        return Math.sqrt(value);
    }

    @Override
    public ItemDistanceAlgorithm getAlgorithm(){
        return ItemDistanceAlgorithm.NORMALIZED_EUCLIDEAN_DISTANCE;
    }

    private double calculateBar(double[] val){
        int num = 0;
        double v = 0d;
        for(int i = 0; i < val.length; i++){
            if(!Double.isNaN(val[i])){
               num++;
               v += val[i];
            }
        }
        return v / num;
    }
}
